////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 CORE Solutions Limited
// All rights reserved.
// PROPRIETARY AND CONFIDENTIAL INFORMATION.
// Use is subject to license terms.
//
// FUNCTION ID      :   FormCommonTemplate.java
// AUTHOR           :   ric.yik
// DATE CREATE      :   2006/5/10
// DESCRIPTION      :
//                  :
//                  :
//                  :
//
// MODIFICATION HISTORY:
// DATE         AUTHOR          VERSION NO.         COMMENT
// -----------  --------------  ------------------  -------------------
// 2006/7/7       Joey.Hua         1.0                Add Season Year Combox
// 2006/5/10      ric.yik         1.0                 source is created.
//
//
//
////////////////////////////////////////////////////////////////////////////////

package com.erp.framework.controller.form;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import com.erp.app.admin.userSetup.pk.UserPk;
import com.erp.app.catalog.itemLine.pk.ItemLinePk;
import com.erp.app.common.ProjectConstants;

import com.erp.app.common.query.CodeDetailsQuery;
import com.erp.app.common.query.CompanyTypesQuery;
import com.erp.app.common.query.CountryCodeQuery;
import com.erp.app.common.query.DeptQuery;
import com.erp.app.common.query.MerchandisingDeptQuery;
import com.erp.app.common.query.ProductCatalogQuery;
import com.erp.app.common.query.QueryObject;
import com.erp.app.common.query.SignatureQuery;
import com.erp.app.common.query.SystemConstantsQuery;
import com.erp.app.common.query.UserQuery;
import com.erp.app.common.select.beans.SelectDelegate;
import com.erp.app.common.util.MapIterator;
import com.erp.app.common.util.NullIterator;
import com.erp.app.setup.accessTeamMaster.pk.AccessTeamHdrPk;
import com.erp.app.setup.codeSetup.pk.CodeDtlPk;
import com.erp.app.setup.codeSetup.pk.CodeHdrPk;
import com.erp.app.setup.country.pk.CountryHdrPk;
import com.erp.app.setup.dept.pk.DeptHdrPk;
import com.erp.app.util.web.WebUtil;
import com.erp.framework.util.BeanUtil;
import com.erp.framework.util.CommonUtil;

public class FormCommonTemplate {

    private static final SelectDelegate selectDelegate = new SelectDelegate();

    private static final Map commonStatusMap = selectDelegate.selectMap(new SystemConstantsQuery().setType(ProjectConstants.CONSTANT_TYPE_ACT_INACT).toQuery());

    private static final Map commonYesNoMap = selectDelegate.selectMap(new SystemConstantsQuery().setType(ProjectConstants.CONSTANT_TYPE_YES_NO).toQuery());

    private static final Map commonApproveRejectMap = selectDelegate.selectMap(new SystemConstantsQuery().setType(ProjectConstants.CONSTANT_TYPE_APPROVE_REJECT).toQuery());

    public Map getCommonStatusMap() {
        return commonStatusMap;
    }

    public Map getCommonYesNoMap() {
        return commonYesNoMap;
    }

    public Map getCommonApproveRejectMap() {
        return commonApproveRejectMap;
    }

    public SelectDelegate getSelectDelegate() {
        return selectDelegate;
    }

    public Iterator getComboboxValues(QueryObject query) {
        String queryString = query.toQuery();
        return this.getComboboxValues(this.selectDelegate.selectMap(queryString));
    }

    public Iterator getComboboxValues(String queryString) {
        return this.getComboboxValues(this.selectDelegate.selectMap(queryString));
    }

    public Iterator getComboboxValues(Map map) {
        return new MapIterator(CommonUtil.getMap(map));
    }

    public Iterator getCommonStatusValues() {
        return this.getComboboxValues(this.getCommonStatusMap());
    }

    public Iterator getCommonYesNoValues() {
        return this.getComboboxValues(this.getCommonYesNoMap());
    }

    public Iterator getCommonApproveRejectValues() {
        return this.getComboboxValues(this.getCommonApproveRejectMap());
    }


    public Iterator getSingletonValues(String value) {
        return (CommonUtil.isEmpty(value)) ? Collections.EMPTY_MAP.keySet().iterator() : this.getComboboxValues(Collections.singletonMap(value, value));
    }

    public Iterator getCodeDetailsValues(CodeHdrPk codePk) {
        return this.getComboboxValues(new CodeDetailsQuery().setCodeHdrPk(codePk));
    }

    public Iterator getCountryValues(CountryHdrPk countryPk){
    	return this.getComboboxValues(new CountryCodeQuery().setCountryHdrPk(countryPk));
    }

    public Iterator getCodeDetailsValues(CodeDtlPk codePk) {
        return this.getComboboxValues(new CodeDetailsQuery().setCodeDtlPk(codePk));
    }

    public Iterator getMerchandisingDeptValues(String companyCode){
    	return this.getComboboxValues(new MerchandisingDeptQuery().setCompanyCode(companyCode));
    }

    public Iterator getMerchandisingDeptValues(DeptHdrPk deptHdrPk){
    	return this.getComboboxValues(new MerchandisingDeptQuery().setDeptHdrPk(deptHdrPk));
    }

    public Iterator getDeptValues(String companyCode){
    	return this.getComboboxValues(new DeptQuery().setCompanyCode(companyCode));
    }

    public Iterator getDeptValues(DeptHdrPk deptHdrPk){
    	return this.getComboboxValues(new DeptQuery().setDeptHdrPk(deptHdrPk));
    }

    public Iterator getProductCatalogValues(ItemLinePk catalogPk) {
        return this.getComboboxValues(new ProductCatalogQuery().setCatalogPk(catalogPk));
    }

    public Iterator getCompanyTypesValues(){
    	return this.getComboboxValues(new CompanyTypesQuery().toQuery());
    }
    
    public Map getCompanyTypesMapValues(){
    	return selectDelegate.selectMap(new CompanyTypesQuery().toQuery());
    }
    
    public Iterator getSingletonValues(Object key, Object value) {
        return this.getComboboxValues(Collections.singletonMap(key, value));
    }

    public Iterator getUserNameValues(Object bean, String propertyName) {
        try {
            String companyCode = String.valueOf(BeanUtil.getPropertyDefault(bean, "companyCode"));
            String userCode = String.valueOf(BeanUtil.getPropertyDefault(bean, propertyName));
            return this.getComboboxValues(new UserQuery().setUserPk(new UserPk(userCode, companyCode)));
        } catch (Exception e) {
            return new NullIterator();
        }
    }
    
    public Iterator getSignatureValues(String companyCode){
    	return this.getComboboxValues(new SignatureQuery().setCompanyCode(companyCode));
    }
    public Iterator getSignatureValues(UserPk userPk){
    	return this.getComboboxValues(new SignatureQuery().setUserPk(userPk));
    }

    public static class FormFileWithSizeLimit implements FormFile {

        private final FormFile formFile;
        private final byte[] fileData;

        public FormFileWithSizeLimit(FormFile file, byte[] fileData) {
            super();
            formFile = file;
            this.fileData = fileData;
        }

        public void destroy() {
            formFile.destroy();
        }

        public String getContentType() {
            return formFile.getContentType();
        }

        public byte[] getFileData() throws FileNotFoundException, IOException {
           return this.fileData;
        }

        public String getFileName() {
            return formFile.getFileName();
        }

        public int getFileSize() {
            return formFile.getFileSize();
        }

        public InputStream getInputStream() throws FileNotFoundException, IOException {
            return formFile.getInputStream();
        }

        public void setContentType(String contentType) {
            formFile.setContentType(contentType);
        }

        public void setFileName(String fileName) {
            formFile.setFileName(fileName);
        }

        public void setFileSize(int filesize) {
            formFile.setFileSize(filesize);
        }

    }

    public FormFile getFormFile(ActionMapping mapping, ActionForm formIn,
            HttpServletRequest request, HttpServletResponse response, ActionErrors errors) throws Exception {
        HttpSession session = request.getSession(false);
        HashMap params = (HashMap) session.getAttribute(ProjectConstants.SESSION_UPLOAD_FILE_RETURN_PARAM);
        session.removeAttribute(ProjectConstants.SESSION_UPLOAD_FILE_RETURN_PARAM);
        if (params == null) return null;
        FormFile file = (FormFile) params.get(ProjectConstants.SESSION_UPLOAD_FILE_RETURN_FORM_FILE);
        if (file == null) {
            return null;
        }
        // retrieve the file name
        String fileName = file.getFileName();
        // retrieve the content type
        String contentType = file.getContentType();

        // retrieve the file data
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InputStream stream = file.getInputStream();
        int imageMaxSizeInKb = ProjectConstants.IMAGE_MAX_SIZE_IN_KB;
        try {
            imageMaxSizeInKb = Integer.parseInt(WebUtil.getPrjParamVal(session, ProjectConstants.PP_IMAGE_MAX_SIZE_IN_KB));
        } catch (NumberFormatException e) {
        }
        if (!CommonUtil.isEmpty(fileName)) {
            byte[] buffer = new byte[8192];
            int bytesRead = 0;

            while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {

                baos.write(buffer, 0, bytesRead);
                if (baos.size() > imageMaxSizeInKb)
                    break;
            }

            if (baos.size() > imageMaxSizeInKb && contentType.startsWith("image")) {
                errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.image.size.exceed", String.valueOf(imageMaxSizeInKb)));
                return null;
            } else {
                return new FormFileWithSizeLimit(file, baos.toByteArray());
            }
        } else {
            return null;
        }
    }
    
    public Map getCodeDtlMap(CodeDtlPk codePk) {
        return selectDelegate.selectMap(new CodeDetailsQuery().setCodeDtlPk(codePk).toQuery());
    }
}
